package operadores.crossover;

import base.ParDeSolucoes;
import base.Solucao;
import base.Vertice;
import java.util.ArrayList;
import java.util.Arrays;

// Representa o operador de crossover CX.
public class CrossoverCX implements OperadorCrossover {

    @Override
    public ParDeSolucoes aplica(ParDeSolucoes pais) {
        Solucao pai1 = pais.getSolucao1();
        Solucao pai2 = pais.getSolucao2();

        int tamanho = pai1.tamanho();
        Vertice[] segmento1 = new Vertice[tamanho];
        Vertice[] segmento2 = new Vertice[tamanho];

        // ciclo inicial do F1
        Vertice aSerCopiado = pai1.getCaminho().get(0);
        do {
            int i = pai1.getCaminho().indexOf(aSerCopiado);
            segmento1[i] = aSerCopiado;

            aSerCopiado = pai2.getCaminho().get(i);
        } while (!aSerCopiado.equals(segmento1[0]));

        // ciclo inicial do F2
        aSerCopiado = pai2.getCaminho().get(0);
        do {
            int i = pai2.getCaminho().indexOf(aSerCopiado);
            segmento2[i] = aSerCopiado;

            aSerCopiado = pai1.getCaminho().get(i);
        } while (!aSerCopiado.equals(segmento2[0]));

        // completa F1 e F2
        for (int i = 0; i < tamanho; i++) {
            if (segmento1[i] == null) {
                segmento1[i] = pai2.getCaminho().get(i);
            }
            if (segmento2[i] == null) {
                segmento2[i] = pai1.getCaminho().get(i);
            }
        }

        Solucao filho1 = new Solucao(new ArrayList<>(Arrays.asList(segmento1)));
        Solucao filho2 = new Solucao(new ArrayList<>(Arrays.asList(segmento2)));
        return new ParDeSolucoes(filho1, filho2);
    }
}
